package com.wits.qso.web.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springside.modules.web.Servlets;

import com.wits.platform.common.constants.ViewType;
import com.wits.platform.common.constants.WebConstants;
import com.wits.platform.common.utils.PageUtil;
import com.wits.platform.common.utils.StringUtil;
import com.wits.platform.web.controller.BaseController;
import com.wits.platform.web.mvc.PageParam;
import com.wits.qso.entity.Btable;
import com.wits.qso.entity.CreContent;
import com.wits.qso.entity.Croom;
import com.wits.qso.service.AidService;
import com.wits.qso.service.AttachmentService;
import com.wits.qso.service.BtableDaoService;
import com.wits.qso.service.CreContentService;
import com.wits.qso.service.CroomService;
import com.wits.qso.service.HomeworkHService;

@Controller
@RequestMapping(value = "qso/croom")
public class CroomController extends BaseController
{

	/**
	 * 注入croomService
	 */
	@Autowired
	private CroomService croomService;
	@Autowired
	private HomeworkHService homeworkHService = null;
	@Autowired
	private AttachmentService attachmentService = null;
	@Autowired
	private AidService aidService = null;
	@Autowired
	private CreContentService creContentService = null;
	@Autowired
	private BtableDaoService btableService = null;
	
	@RequestMapping(value = "/toList")
	public String toList() {
		return "qso/croom/list";
	}

	/**
	 * 加载教室设定信息列表
	 * 
	 * @param model
	 * @param page
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/list")
	@ResponseBody
	public String list(Model model, @ModelAttribute("page") PageParam page, HttpServletRequest req) {
		Map<String, Object> searchParams = Servlets.getParametersStartingWith( req, "search_" );
		Page<Croom> listPage = croomService.findPage( Croom.class, searchParams, page );
		model.addAttribute( "searchParams", Servlets.encodeParameterStringWithPrefix( searchParams, "search_" ) );
		return PageUtil.toAjaxPageResult( listPage.getTotalElements(), listPage.getContent() );
	}

	/**
	 * 教室信息列表上方按钮的触发事件处理
	 * 
	 * @param model
	 * @param viewType
	 * @param crmId
	 * @return
	 */
	@RequestMapping(value = "/view/{viewType}")
	public String toView(Model model, @PathVariable String viewType, @RequestParam String crmId) {
		List<Btable> btables = new ArrayList<Btable>();
		if (ViewType.Add.getView().equals( viewType )) {
			model.addAttribute( WebConstants.COMMAND, new Croom() );

			for (int i = 0; i < 10; i++) {
				btables.add( new Btable() );
			}
		} else {
			Croom croom = croomService.getOne( crmId );
			model.addAttribute( WebConstants.COMMAND, croom );
			// 傳入每周第一次的開課星期，查詢課表
			btables = btableService.findByCroomAndWeDay( String.valueOf( croom.getWeekT() ), crmId );
			int btableSize = btables.size();

			if (10 > btableSize) {
				for (int i = btableSize; i < 10; i++) {
					btables.add( new Btable() );
				}
			}
		}

		model.addAttribute( "btables", btables );
		model.addAttribute( "viewType", viewType );
		return "qso/croom/form";
	}

	/**
	 * 新增、修改教室信息
	 * 
	 * @param model
	 * @param command
	 * @param viewType
	 * @param result
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/save", method = { RequestMethod.POST })
	@ResponseBody
	public Object save(Model model, @ModelAttribute("command") @Valid Croom command, @RequestParam String viewType, @RequestParam(value = "weekT") int weekT,
	        @RequestParam(value = "weekF") int weekF, @RequestParam(value = "crmClassNum") int crmClassNum, BindingResult result, HttpServletRequest request) {
		Map<String, Object> clsParams = Servlets.getParametersStartingWith( request, "cls-" );

		if (result.hasErrors()) {
			model.addAttribute( WebConstants.COMMAND, command );
			return toView( model, viewType, command.getCrmId() );
		}

		if (command.getDateF().compareTo( command.getDateT() ) > 0) {
			return ajaxDoneError( "「开放日期止」不能早于「开放日期起」" );
		}
		
		Calendar current = Calendar.getInstance();
		Date classStartTime = null;
		Date classEndtime = null;
		Date exClassEndtime = null;
		for (int i = 1; i <= crmClassNum; i++) {
			current.set( Calendar.HOUR_OF_DAY, Integer.parseInt( (String) clsParams.get( "start-hour-" + i ) ) );
			current.set( Calendar.MINUTE, Integer.parseInt( (String) clsParams.get( "start-min-" + i ) ) );
			current.set( Calendar.SECOND, 0 );
			current.set( Calendar.MILLISECOND, 0 );
			classStartTime = current.getTime();

			current.set( Calendar.HOUR_OF_DAY, Integer.parseInt( (String) clsParams.get( "end-hour-" + i ) ) );
			current.set( Calendar.MINUTE, Integer.parseInt( (String) clsParams.get( "end-min-" + i ) ) );
			current.set( Calendar.SECOND, 0 );
			current.set( Calendar.MILLISECOND, 0 );
			classEndtime = current.getTime();

			if (classStartTime.compareTo( classEndtime ) >= 0) {
				return ajaxDoneError( "课节时间不能重复" );
			}

			if (1 != i) {
				if (classStartTime.compareTo( exClassEndtime ) <= 0) {
					return ajaxDoneError( "课节时间不能重复" );
				}
			}

			exClassEndtime = classEndtime;
		}

		if (ViewType.Add.getView().equals( viewType )) {
			if (croomService.hasByTitleAndCode( command.getCrmTitle(), command.getCrmCode() )) {
				return ajaxDoneError( "已經存在相同教室名稱與教室編號" );
			}
			command.setDateCre( new Date() );
			command.setUserCre( getCurrentUserId() );
		} else {
			command.setDateUpd( new Date() );
			command.setUserUpd( getCurrentUserId() );
		}

		try {
			if (StringUtils.isNotBlank( command.getCrmId() )) {
				try {
					deleteBtable( command.getCrmId() );
				} catch (Throwable cause) {
					return ajaxDoneError( "教室已经被引用，无法修改" );
				}
			}

			// Java Calendar Day of Week
			// sunday = 1, monday = 2 .. saturday = 7
			Calendar calendar = Calendar.getInstance();
			List<Btable> btables = new ArrayList<Btable>();

			List<Integer> weekdays=new ArrayList<Integer>();
			if(weekT<=weekF){
				for(int weekday=weekT;weekday<=weekF;weekday++){
					weekdays.add(weekday);
				}
			}else{
				for(int weekday=weekT;weekday<=7;weekday++){
					weekdays.add(weekday);
				}
				for(int weekday=1;weekday<=weekF;weekday++){
					weekdays.add(weekday);
				}
			}
			
			for (int i = 0; i < weekdays.size(); i++) {
				int weekday=weekdays.get(i);
				for (int clssNum = 1; clssNum <= crmClassNum; clssNum++) {
					String startHour = (String) clsParams.get( "start-hour-" + clssNum );
					String startMin = (String) clsParams.get( "start-min-" + clssNum );
					String endHour = (String) clsParams.get( "end-hour-" + clssNum );
					String endMin = (String) clsParams.get( "end-min-" + clssNum );

					// 時間不可以為空值
					if (StringUtils.isNotBlank( startHour ) && StringUtils.isNotBlank( startMin ) && 
							StringUtils.isNotBlank( endHour ) && StringUtils.isNotBlank( endMin )) {
						Date start = command.getDateF();
						Date end = command.getDateT();
						
						while ((start.compareTo( end )) <= 0) {
							calendar.clear();
							calendar.setTime( start );

							if (weekday == calendar.get( Calendar.DAY_OF_WEEK )) {
								Btable entity = new Btable();
								entity.setCalss( String.valueOf( clssNum ) );

								calendar.set( Calendar.HOUR_OF_DAY, Integer.valueOf( startHour ) );
								calendar.set( Calendar.MINUTE, Integer.valueOf( startMin ) );
								calendar.set( Calendar.SECOND, 0 );
								entity.setTime_start( calendar.getTime() );

								calendar.set( Calendar.HOUR_OF_DAY, Integer.valueOf( endHour ) );
								calendar.set( Calendar.MINUTE, Integer.valueOf( endMin ) );
								calendar.set( Calendar.SECOND, 0 );
								entity.setTime_end( calendar.getTime() );

								entity.setWeday( String.valueOf( weekday ) );
								entity.setDateCre( new Date() );
								entity.setUserCre( getCurrentUserId() );

								btables.add( entity );
							}

							calendar.add( Calendar.DATE, 1 );
							start = calendar.getTime();
						}
					}
				}
			}

			command = croomService.save( command );

			for (Btable entity : btables) {
				entity.setCrmid( command );
				
				logger.info( "{}", entity );
				btableService.save( entity );
			}

			return ajaxDoneSuccess( this.getText( "save.success" ) );
		} catch (Exception e) {
			logger.error( e.getMessage(), e );
			return ajaxDoneError( this.getText( "save.failed" ), e );
		}
	}

	/**
	 * 删除教室信息
	 * 
	 * @param ids
	 * @return
	 */
	@RequestMapping(value = "/delete")
	@ResponseBody
	public Object delete(String ids) {
		boolean hasSusscesed = false;
		boolean hasErrored = false;
		
		List<String> idList = Arrays.asList( StringUtil.split( ids, "," ) );
		for (String id : idList) {
			try {
				deleteBtable( id );
				croomService.delete( id );
				hasSusscesed = true;
			} catch (Exception e) {
				hasErrored = true;
			}
		}
		if (hasSusscesed) {
			if (hasErrored) {
				return ajaxDoneError( "有些被引用的教室无法删除" );
			} else {
				return ajaxDoneSuccess(this.getText("delete.success"));
			}
		} else {
			return ajaxDoneError( "所选教室已经被引用，无法删除" );
		}
	}

	/**
	 * 唯一键检查
	 * 
	 * @param crmId
	 * @param oldCrmId
	 * @return
	 */
	@RequestMapping(value = "/checkUniqueId")
	@ResponseBody
	public boolean checkUniqueId(@RequestParam String crmId, @RequestParam String oldCrmId) {
		if (crmId.equals( oldCrmId )) {
			return true;
		}
		Croom obj = croomService.getOne( crmId );
		return obj == null;
	}

	protected void deleteBtable(String crmId) {
		List<Btable> removedBtableList = btableService.findByCroom( crmId );
		/*
		 * 刪除相依資料 btable -> crecontent crecontent -> aid, crecontent -> homeworkh aid -> attachment, homeworkh -> attachment
		 */
		for (Btable removedBtable : removedBtableList) {
			List<CreContent> removedCreContentList = creContentService.findByBtable( removedBtable );
			if (null != removedCreContentList && !removedCreContentList.isEmpty()) {
				for (CreContent removedCreContent : removedCreContentList) {
					attachmentService.deleteByBusinessId( removedCreContent.getAidId().getId() );
					attachmentService.deleteByBusinessId( removedCreContent.getHwkhId().getId() );

					aidService.delete( removedCreContent.getAidId().getId() );
					homeworkHService.delete( removedCreContent.getHwkhId().getId() );
					creContentService.delete( removedCreContent.getId() );
				}
			}
		}

		btableService.deleteByCroom( crmId );
	}
}
